{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Classical probability distributions can be written as a stochastic vector, which can be transformed to another stochastic vector by applying a stochastic matrix. In other words, the evolution of stochastic vectors can be described by a stochastic matrix.\n",
    "\n",
    "Quantum states also evolve and their evolution is described by unitary matrices. This leads to some interesting properties in quantum computing. Unitary evolution is true for a closed system, that is, a quantum system perfectly isolated from the environment. This is not the case in the quantum computers we have today: these are open quantum systems that evolve differently due to to uncontrolled interactions with the environment. In this notebook, we take a glimpse at both types of evolution.\n",
    "\n",
    "\n",
    "# Unitary evolution\n",
    "\n",
    "A unitary matrix has the property that its conjugate transpose is its inverse. Formally, it means that a matrix $U$ is unitary if $UU^\\dagger=U^\\dagger U=\\mathbb{1}$, where $^\\dagger$ stands for conjugate transpose, and $\\mathbb{1}$ is the identity matrix. A quantum computer is a machine that implements unitary operations.\n",
    "\n",
    "As an example, we have seen the NOT operation before, which is performed by the X gate in a quantum computer. While the generic discussion on gates will only occur in a subsequent notebook, we can study the properties of the X gate. Its matrix representation is $X = \\begin{bmatrix} 0 & 1\\\\ 1 & 0\\end{bmatrix}$. Let's check if it is indeed unitary:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-19T19:49:07.614968Z",
     "start_time": "2018-11-19T19:49:07.530927Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "XX^dagger\n",
      "[[1 0]\n",
      " [0 1]]\n",
      "X^daggerX\n",
      "[[1 0]\n",
      " [0 1]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "X = np.array([[0, 1], [1, 0]])\n",
    "print(\"XX^dagger\")\n",
    "print(X.dot(X.T.conj()))\n",
    "print(\"X^daggerX\")\n",
    "print(X.T.conj().dot(X))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It looks like a legitimate unitary operation. The unitary nature ensures that the $l_2$ norm is preserved, that is, quantum states are mapped to quantum states."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-19T19:49:07.626531Z",
     "start_time": "2018-11-19T19:49:07.618259Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The norm of the state |0> before applying X\n",
      "1.0\n",
      "The norm of the state after applying X\n",
      "1.0\n"
     ]
    }
   ],
   "source": [
    "print(\"The norm of the state |0> before applying X\")\n",
    "zero_ket = np.array([[1], [0]])\n",
    "print(np.linalg.norm(zero_ket))\n",
    "print(\"The norm of the state after applying X\")\n",
    "print(np.linalg.norm(X.dot(zero_ket)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Furthermore, since the unitary operation is a matrix, it is linear. Measurements are also represented by matrices. These two observations imply that everything a quantum computer implements is actually linear. If we want to see some form of nonlinearity, that must involve some classical intervention.\n",
    "\n",
    "Another consequence of the unitary operations is reversibility. Any unitary operation can be reversed. Quantum computing libraries often provide a function to reverse entire circuits. Reversing the X gate is simple: we just apply it again (its conjugate transpose is itself, therefore $X^2=\\mathbb{1}$)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-19T19:49:08.710098Z",
     "start_time": "2018-11-19T19:49:07.629733Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/pwittek/.anaconda3/envs/qiskit/lib/python3.7/site-packages/marshmallow/schema.py:364: ChangedInMarshmallow3Warning: strict=False is not recommended. In marshmallow 3.0, schemas will always be strict. See https://marshmallow.readthedocs.io/en/latest/upgrading.html#schemas-are-always-strict\n",
      "  ChangedInMarshmallow3Warning\n",
      "/home/pwittek/.anaconda3/envs/qiskit/lib/python3.7/site-packages/marshmallow/schema.py:364: ChangedInMarshmallow3Warning: strict=False is not recommended. In marshmallow 3.0, schemas will always be strict. See https://marshmallow.readthedocs.io/en/latest/upgrading.html#schemas-are-always-strict\n",
      "  ChangedInMarshmallow3Warning\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.+0.j 0.+0.j]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/pwittek/.anaconda3/envs/qiskit/lib/python3.7/site-packages/marshmallow/schema.py:364: ChangedInMarshmallow3Warning: strict=False is not recommended. In marshmallow 3.0, schemas will always be strict. See https://marshmallow.readthedocs.io/en/latest/upgrading.html#schemas-are-always-strict\n",
      "  ChangedInMarshmallow3Warning\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister\n",
    "from qiskit import execute\n",
    "from qiskit import BasicAer\n",
    "from qiskit.tools.visualization import circuit_drawer\n",
    "np.set_printoptions(precision=3, suppress=True)\n",
    "\n",
    "backend_statevector = BasicAer.get_backend('statevector_simulator')\n",
    "q = QuantumRegister(1)\n",
    "c = ClassicalRegister(1)\n",
    "circuit = QuantumCircuit(q, c)\n",
    "circuit.x(q[0])\n",
    "circuit.x(q[0])\n",
    "job = execute(circuit, backend_statevector)\n",
    "print(job.result().get_statevector(circuit))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "which is exactly $|0\\rangle$ as we would expect.\n",
    "\n",
    "In the next notebook, you will learn about classical and quantum many-body systems and the Hamiltonian. In the notebook on adiabatic quantum computing, you will learn that a unitary operation is in fact the Schrödinger equation solved for a Hamiltonian for some duration of time. This connects the computer science way of thinking about gates and unitary operations to actual physics, but there is some learning to be done before we can make that connection. Before that, let us take another look at the interaction with the environment."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interaction with the environment: open systems\n",
    "\n",
    "Actual quantum systems are seldom closed: they constantly interact with their environment in a largely uncontrolled fashion, which causes them to lose coherence. This is true for current and near-term quantum computers too.\n",
    "\n",
    "<img src=\"figures/open_system.svg\" alt=\"A quantum processor as an open quantum system\" style=\"width: 400px;\"/>\n",
    "\n",
    "This also means that their actual time evolution is not described by a unitary matrix as we would want it, but some other operator (the technical name for it is a completely positive trace-preserving map).\n",
    "\n",
    "Quantum computing libraries often offer a variety of noise models that mimic different types of interaction, and increasing the strength of the interaction with the environment leads to faster decoherence. The timescale for decoherence is often called $T_2$ time. Among a couple of other parameters, $T_2$ time is critically important for the number of gates or the duration of the quantum computation we can perform.\n",
    "\n",
    "A very cheap way of studying the effects of decoherence is mixing a pure state with the maximally mixed state $\\mathbb{1}/2^d$, where $d$ is the number of qubits, with some visibility parameter in $[0,1]$. This way we do not have to specify noise models or any other map modelling decoherence. For instance, we can mix the $|\\phi^+\\rangle$ state with the maximally mixed state:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-19T19:49:08.730307Z",
     "start_time": "2018-11-19T19:49:08.714253Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Maximum visibility is a pure state:\n",
      "[[0.5 0.  0.  0.5]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.  0.  0.  0. ]\n",
      " [0.5 0.  0.  0.5]]\n",
      "The state is still entangled with visibility 0.8:\n",
      "[[0.45 0.   0.   0.4 ]\n",
      " [0.   0.05 0.   0.  ]\n",
      " [0.   0.   0.05 0.  ]\n",
      " [0.4  0.   0.   0.45]]\n",
      "Entanglement is lost by 0.6:\n",
      "[[0.4 0.  0.  0.3]\n",
      " [0.  0.1 0.  0. ]\n",
      " [0.  0.  0.1 0. ]\n",
      " [0.3 0.  0.  0.4]]\n",
      "Barely any coherence remains by 0.2:\n",
      "[[0.3 0.  0.  0.1]\n",
      " [0.  0.2 0.  0. ]\n",
      " [0.  0.  0.2 0. ]\n",
      " [0.1 0.  0.  0.3]]\n"
     ]
    }
   ],
   "source": [
    "def mixed_state(pure_state, visibility):\n",
    "    density_matrix = pure_state.dot(pure_state.T.conj())\n",
    "    maximally_mixed_state = np.eye(4)/2**2\n",
    "    return visibility*density_matrix + (1-visibility)*maximally_mixed_state\n",
    "\n",
    "ϕ = np.array([[1],[0],[0],[1]])/np.sqrt(2)\n",
    "print(\"Maximum visibility is a pure state:\")\n",
    "print(mixed_state(ϕ, 1.0))\n",
    "print(\"The state is still entangled with visibility 0.8:\")\n",
    "print(mixed_state(ϕ, 0.8))\n",
    "print(\"Entanglement is lost by 0.6:\")\n",
    "print(mixed_state(ϕ, 0.6))\n",
    "print(\"Barely any coherence remains by 0.2:\")\n",
    "print(mixed_state(ϕ, 0.2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another way to look at what happens to a quantum state in an open system is through equilibrium processes. Think of a cup of coffee: left alone, it will equilibrate with the environment, eventually reaching the temperature of the environment. This includes energy exchange. A quantum state does the same thing and the environment has a defined temperature, just the environment of a cup of coffee.\n",
    "\n",
    "The equilibrium state is called the thermal state. It has a very specific structure and we will revisit it, but for now, suffice to say that the energy of the samples pulled out of a thermal state follows a Boltzmann distribution. The Boltzmann -- also called Gibbs -- distribution is described as $P(E_i) = \\frac {e^{-E_{i}/T}}{\\sum _{j=1}^{M}{e^{-E_{j}/T}}}$, where $E_i$ is an energy, and $M$ is the total number of possible energy levels. Temperature enters the definition: the higher the temperature, the closer we are to the uniform distribution. In the infinite temperature limit, it recovers the uniform distribution. At high temperatures, all energy levels have an equal probability. In contrast, at zero temperature, the entire probability mass is concentrated on the lowest energy level, the ground state energy. To get a sense of this, let's plot the Boltzmann distribution with vastly different temperatures:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-19T19:49:09.226294Z",
     "start_time": "2018-11-19T19:49:08.733112Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f0748055a20>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "temperatures = [.5, 5, 2000]\n",
    "energies = np.linspace(0, 20, 100)\n",
    "fig, ax = plt.subplots()\n",
    "for i, T in enumerate(temperatures):\n",
    "    probabilities = np.exp(-energies/T)\n",
    "    Z = probabilities.sum()\n",
    "    probabilities /= Z\n",
    "    ax.plot(energies, probabilities, linewidth=3, label = \"$T_\" + str(i+1)+\"$\")\n",
    "ax.set_xlim(0, 20)\n",
    "ax.set_ylim(0, 1.2*probabilities.max())\n",
    "ax.set_xticks([])\n",
    "ax.set_yticks([])\n",
    "ax.set_xlabel('Energy')\n",
    "ax.set_ylabel('Probability')\n",
    "ax.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here $T_1<T_2<T_3$. Notice that $T_1$ is a low temperature, and therefore it is highly peaked at low energy levels. In contrast, $T_3$ is a very high temperature and the probability distribution is almost completely flat."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
